package org.example.weboj.controller;

import org.example.weboj.dto.CodeExecutionRequest;
import org.example.weboj.dto.CodeExecutionResult;
import org.example.weboj.dto.ProblemDTO;
import org.example.weboj.dto.TestCaseDTO;
import org.example.weboj.service.CodeExecutionService;
import org.example.weboj.service.IProblemsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/code")
public class CodeExecutionController {

    @Autowired
    private CodeExecutionService codeExecutionService;

    @Autowired
    private IProblemsService problemsService;

    /**
     * 执行代码并验证测试用例
     * @param problemId 题目ID
     * @param request 包含代码和语言的请求体
     * @return 执行结果
     */
    @PostMapping("/execute/{problemId}")
    public ResponseEntity<?> executeCode(
            @PathVariable Long problemId,
            @RequestBody Map<String, String> request) {
        try {
            // 1. 获取题目信息
            ProblemDTO problem = problemsService.getProblemDTOById(problemId);
            if (problem == null) {
                return ResponseEntity.badRequest().body("Problem not found");
            }

            // 2. 获取代码和语言
            String code = request.get("code");
            String language = request.get("language");
            if (code == null || language == null) {
                return ResponseEntity.badRequest().body("Code and language are required");
            }

            // 3. 执行所有测试用例
            List<CodeExecutionResult> results = new ArrayList<>();
            for (TestCaseDTO testCase : problem.getTestCases()) {
                CodeExecutionRequest executionRequest = new CodeExecutionRequest();
                executionRequest.setCode(code);
                executionRequest.setLanguage(language);
                executionRequest.setInput(testCase.getInput());
                executionRequest.setExpectedOutput(testCase.getExpectedOutput());
                executionRequest.setMemoryLimit(problem.getMemoryLimit());
                executionRequest.setTimeLimit(problem.getTimeLimit());

                CodeExecutionResult result = codeExecutionService.executeCode(executionRequest);
                results.add(result);
            }

            // 4. 返回执行结果
            return ResponseEntity.ok(results);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("Error executing code: " + e.getMessage());
        }
    }


    /**
     * 执行示例测试用例
     * @param problemId 题目ID
     * @param request 包含代码和语言的请求体
     * @return 执行结果
     */
    @PostMapping("/execute/{problemId}/sample")
    public ResponseEntity<?> executeSampleTestCases(
            @PathVariable Long problemId,
            @RequestBody Map<String, String> request) {
        try {
            // 1. 获取题目信息
            ProblemDTO problem = problemsService.getProblemDTOById(problemId);
            if (problem == null) {
                return ResponseEntity.badRequest().body("Problem not found");
            }

            // 2. 获取代码和语言
            String code = request.get("code");
            String language = request.get("language");
            if (code == null || language == null) {
                return ResponseEntity.badRequest().body("Code and language are required");
            }

            // 3. 执行示例测试用例
            List<CodeExecutionResult> results = new ArrayList<>();
            for (TestCaseDTO testCase : problem.getTestCases()) {
                if (testCase.getIsSample()) {
                    CodeExecutionRequest executionRequest = new CodeExecutionRequest();
                    executionRequest.setCode(code);
                    executionRequest.setLanguage(language);
                    executionRequest.setInput(testCase.getInput());
                    executionRequest.setExpectedOutput(testCase.getExpectedOutput());
                    executionRequest.setMemoryLimit(problem.getMemoryLimit());
                    executionRequest.setTimeLimit(problem.getTimeLimit());

                    CodeExecutionResult result = codeExecutionService.executeCode(executionRequest);
                    results.add(result);
                }
            }

            // 4. 返回执行结果
            return ResponseEntity.ok(results);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("Error executing code: " + e.getMessage());
        }
    }

    /**
     * 执行用户自定义输入的代码
     * @param problemId 题目ID
     * @param request 包含代码、语言和自定义输入的请求体
     * @return 执行结果
     */
    @PostMapping("/execute/{problemId}/custom")
    public ResponseEntity<?> executeCustomInput(
            @PathVariable Long problemId,
            @RequestBody Map<String, String> request) {
        try {
            // 1. 获取题目信息
            ProblemDTO problem = problemsService.getProblemDTOById(problemId);
            if (problem == null) {
                return ResponseEntity.badRequest().body("Problem not found");
            }

            // 2. 获取代码、语言和自定义输入
            String code = request.get("code");
            String language = request.get("language");
            String customInput = request.get("input");
            
            if (code == null || language == null) {
                return ResponseEntity.badRequest().body("Code and language are required");
            }
            
            if (customInput == null || customInput.trim().isEmpty()) {
                return ResponseEntity.badRequest().body("Custom input is required");
            }

            // 3. 执行代码
            CodeExecutionRequest executionRequest = new CodeExecutionRequest();
            executionRequest.setCode(code);
            executionRequest.setLanguage(language);
            executionRequest.setInput(customInput);
            executionRequest.setMemoryLimit(problem.getMemoryLimit());
            executionRequest.setTimeLimit(problem.getTimeLimit());

            CodeExecutionResult result = codeExecutionService.executeCode(executionRequest);
            
            // 4. 返回执行结果
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("Error executing code: " + e.getMessage());
        }
    }
}
